﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace BaiDuSitemap.DataBase
{
    public partial class ucDataBase : UserControl
    {
        #region Attributes

        private Thread myThread = null;
        private delegate RichTextBox myDeleGategetRichTextBox();
        private delegate void myDeleGateSetTabControl(DataTable dt, int count, string err);

        private TabPage tpResult = null;
        private DataGridView dgvResult = null;
        private ImageList myImageList = null;
        private float mySize = 10;
        private float DefSize = 10;
        private float MaxSize = 30;
        private float MinSize = 3;

        private Regex regex = new Regex(@"^((update|delete|insert).*)|(select(.*?)into.*)");

        #endregion

        #region ucDataBase

        public ucDataBase()
        {
            InitializeComponent();
        }

        private void ucDataBase_Load(object sender, EventArgs e)
        {
            InitTreeView();
            DefSize = this.rtbSQL.Font.Size;
        }

        private void ucDataBase_SizeChanged(object sender, EventArgs e)
        {
            this.tabControlResult.Refresh();
            this.picClose.Location = new Point(this.Width - this.picClose.Width - 3, 3);
            this.gbLogin.Location = new Point((this.pLogin.Width - this.gbLogin.Width) / 2, (this.pLogin.Height - this.gbLogin.Height) / 3);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.statusStrip1.BackColor = Sitemap.AeroColor;
        }

        #endregion

        #region Event

        #region Button

        private void btnLogin_Click(object sender, EventArgs e)
        {
            if (this.tbUserID.Text.Length == 0)
            {
                MessageBox.Show("请输入账号");
                ShowLoginError("账号不能为空");
                return;
            }

            if(DBO.DataBase.Login(this.tbUserID.Text.Trim(),QT.Tools.MD5(this.tbPass.Text.Trim())))
            {
                this.pLogin.Visible = false;
                this.ParentForm.AcceptButton = null;
            }
            else
            {
                ShowLoginError("用户名或密码错误");
                MessageBox.Show("登入失败，用户名或密码错误");
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.picClose_Click(sender, e);
        }

        #endregion

        #region menuStrip

        #region File

        private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
        {

            if (this.rtbSQL.Text.Length == 0 && MessageBox.Show("当前内容将会被清空，确认要继续吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) return;

            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            string txtFileName = null;
            try
            {
                myOpenFileDialog.Filter = "SQL file (*.sql)|*.sql|text file (*.txt;*.log)|*.txt;*.log|AllFiles (*.*)|*.*";
                if (DialogResult.Cancel == myOpenFileDialog.ShowDialog())
                {
                    return;
                }

                txtFileName = myOpenFileDialog.FileName;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                myOpenFileDialog.Dispose();
            }

            FileStream ifs = null;
            StreamReader sr = null;

            try
            {
                ifs = new FileStream(txtFileName, FileMode.Open, FileAccess.Read);
                sr = new StreamReader(ifs);

                this.rtbSQL.Text = sr.ReadToEnd();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                ifs.Dispose();
            }
        }

        private void toolStripMenuItem_Save_Click(object sender, EventArgs e)
        {
            string txtFileName = this.rtbSQL.Tag == null ? "" : this.rtbSQL.Tag.ToString();

            if (string.IsNullOrEmpty(txtFileName) || !File.Exists(txtFileName))
            {
                SaveFileDialog mySaveFileDialog = new SaveFileDialog();
                try
                {
                    mySaveFileDialog.ValidateNames = true;
                    mySaveFileDialog.Filter = "SQL file(*.sql)|*.sql|text file (*.txt;*.log)|*.txt;*.log|AllFiles (*.*)|*.*";
                    mySaveFileDialog.AddExtension = true;
                    mySaveFileDialog.FilterIndex = 1;
                    mySaveFileDialog.DefaultExt = "sql";
                    mySaveFileDialog.FileName = "mySql.sql";

                    if (mySaveFileDialog.ShowDialog() == DialogResult.Cancel) return;
                    txtFileName = mySaveFileDialog.FileName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    mySaveFileDialog.Dispose();
                }
            }

            try
            {
                this.rtbSQL.SaveFile(txtFileName, RichTextBoxStreamType.PlainText);
                MessageBox.Show("保存成功");
                this.rtbSQL.Tag = txtFileName;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region Edit

        private void toolStripMenuItem_Undo_Click(object sender, EventArgs e)
        {
            this.rtbSQL.Undo();
        }

        private void toolStripMenuItem_Redo_Click(object sender, EventArgs e)
        {
            this.rtbSQL.Redo();
        }

        private void toolStripMenuItem_Cut_Click(object sender, EventArgs e)
        {
            this.rtbSQL.Cut();
        }

        private void toolStripMenuItem_Copy_Click(object sender, EventArgs e)
        {
            this.rtbSQL.Copy();
        }

        private void toolStripMenuItem_Paste_Click(object sender, EventArgs e)
        {
            this.rtbSQL.Paste();
        }

        private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
        {
            this.rtbSQL.SelectAll();
        }

        private void toolStripMenuItem_Increase_Click(object sender, EventArgs e)
        {
            mySize = this.rtbSQL.Font.Size;
            if (mySize < MaxSize) this.rtbSQL.Font = new Font(this.rtbSQL.Font.FontFamily, ++mySize, this.rtbSQL.Font.Style);
            SetFontSizeButton();
        }

        private void toolStripMenuItem_Decrease_Click(object sender, EventArgs e)
        {
            mySize = this.rtbSQL.Font.Size;
            if (mySize > MinSize) this.rtbSQL.Font = new Font(this.rtbSQL.Font.FontFamily, --mySize, this.rtbSQL.Font.Style);
            SetFontSizeButton();
        }

        private void toolStripMenuItem_Default_Click(object sender, EventArgs e)
        {
            mySize = DefSize;
            this.rtbSQL.Font = new Font(this.rtbSQL.Font.FontFamily, mySize, this.rtbSQL.Font.Style);
            SetFontSizeButton();
        }

        #endregion

        #region Tools

        private void toolStripMenuItem_Exec_Click(object sender, EventArgs e)
        {
            myThread = new Thread(new ThreadStart(ThreadSQL));
            myThread.Start();
        }

        private void toolStripMenuItem_Stop_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive) myThread.Abort();
        }

        #endregion

        #region Help

        private void toolStripMenuItem_Info_Click(object sender, EventArgs e)
        {
            MessageBox.Show("版权所有：安全组 2012-" + DateTime.Now.ToString("yyyy"), "萍乡互通有限责任公司");
        }

        #endregion

        #endregion

        #region toolStrip

        private void toolStripButton_Info_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Info_Click(sender, e);
        }

        private void toolStripButton_Open_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Open_Click(sender, e);
        }

        private void toolStripButton_Save_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Save_Click(sender, e);
        }

        private void toolStripButton_Cut_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Cut_Click(sender, e);
        }

        private void toolStripButton_Copy_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Copy_Click(sender, e);
        }

        private void toolStripButton_Paste_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Paste_Click(sender, e);
        }

        private void toolStripButton_SelectAll_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_SelectAll_Click(sender, e);
        }

        private void toolStripButton_Undo_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Undo_Click(sender, e);
        }

        private void toolStripButton_Redo_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Redo_Click(sender, e);
        }

        private void toolStripButton_Exec_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Exec_Click(sender, e);
        }

        private void toolStripButton_Stop_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Stop_Click(sender, e);
        }

        private void toolStripButton_Increase_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Increase_Click(sender, e);
        }

        private void toolStripButton_Decrease_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Decrease_Click(sender, e);
        }

        private void toolStripButton_Default_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Default_Click(sender, e);
        }

        #endregion

        #region Picture

        private void picClose_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行数据操作，确认要关闭吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }

                myThread.Abort();
            }

            this.Dispose();
        }

        private void picClose_MouseEnter(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close02;
        }

        private void picClose_MouseLeave(object sender, EventArgs e)
        {
            this.picClose.Image = Properties.Resources.close01;
        }

        #endregion

        #endregion

        #region Thread

        private void ThreadSQL()
        {
            try
            {
                RichTextBox myRichTextBox = getRichTextBox();
                string sql = (string.IsNullOrEmpty(myRichTextBox.SelectedText) ? myRichTextBox.Text : myRichTextBox.SelectedText).Trim();

                if (string.IsNullOrEmpty(sql)) return;

                DataTable dt = null;
                int exeCount = -1;
                string err = null;
                try
                {
                    if (regex.IsMatch(sql)) exeCount = DBO.DataBase.execSQL(sql);
                    else dt = DBO.DataBase.getData(sql);
                }
                catch (ThreadAbortException)
                {
                    err = "操作已取消";
                }
                catch (Exception ex)
                {
                    err = ex.Message;
                }
                finally
                {
                    SetTabControl(dt, exeCount, err);
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region Method

        private void InitImageList()
        {
            myImageList.Images.Add("database", global::BaiDuSitemap.Properties.Resources.database);
            myImageList.Images.Add("floderclose", global::BaiDuSitemap.Properties.Resources.floderoclose);
            myImageList.Images.Add("folderopen", global::BaiDuSitemap.Properties.Resources.floderopen);
            myImageList.Images.Add("floderopenhover", global::BaiDuSitemap.Properties.Resources.floderopenhover);
            myImageList.Images.Add("table", global::BaiDuSitemap.Properties.Resources.table);
            myImageList.Images.Add("column", global::BaiDuSitemap.Properties.Resources.column);
        }

        private void InitTreeView()
        {
            this.tvDataList.ImageList = myImageList;
            this.tvDataList.StateImageList = myImageList;
            TreeNode root = tvDataList.Nodes.Add("root", "[ACCESS数据库]", "database", "database");
            root.Expand();
            TreeNode table = root.Nodes.Add("table", "表", 1, 3);
            table.Expand();
            DataTable dt = DBO.DataBase.getTabels();
            foreach (DataRow dr in dt.Rows)
            {
                TreeNode myNode = table.Nodes.Add("table_" + dr[0].ToString(), dr[0].ToString().ToUpper(), 4);
                TreeNode column = myNode.Nodes.Add("column", "列 (数据类型)", 1, 3);
                DataTable dtColumns = DBO.DataBase.getColumns(dr[0].ToString());
                foreach (DataColumn dc in dtColumns.Columns)
                {
                    column.Nodes.Add("column_" + dc.ColumnName, dc.ColumnName.ToUpper() + " (" + dc.DataType.Name + ")", 5);
                }
            }
        }

        public bool Closing()
        {
            if (myThread != null && myThread.IsAlive) return false;
            return true;
        }

        private bool getStatus()
        {
            if ((myThread != null && myThread.IsAlive)) return false;
            return true;
        }

        private void SetFontSizeButton()
        {
            if (mySize <= MinSize) this.toolStripButton_Decrease.Enabled = false;
            if (mySize >= MaxSize) this.toolStripButton_Increase.Enabled = false;
            if (mySize < MaxSize && mySize > MinSize)
            {
                this.toolStripButton_Increase.Enabled = true;
                this.toolStripButton_Decrease.Enabled = true;
            }
        }

        private RichTextBox getRichTextBox()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetRichTextBox(getRichTextBox)) as RichTextBox;
            }
            else
            {
                return this.rtbSQL;
            }
        }

        private void SetTabControl(DataTable dt, int count, string err)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetTabControl(SetTabControl), new object[] { dt, count, err });
            }
            else
            {
                if ((dt == null && count == -1 && err == null))
                {
                    this.rtbMsg.Text = "操作错误，原因未知";
                    this.tabControlResult.SelectTab(this.tabPageMsg);
                    if (this.tabControlResult.Contains(tpResult)) this.tabControlResult.Controls.Remove(tpResult);
                    return;
                }
                else if (count != -1)
                {
                    this.rtbMsg.Text = string.Format("{0}行受影响", count);
                    this.tabControlResult.SelectTab(this.tabPageMsg);
                    if (this.tabControlResult.Contains(tpResult)) this.tabControlResult.Controls.Remove(tpResult);
                    return;
                }
                else if (err != null)
                {
                    this.rtbMsg.Text = err;
                    this.tabControlResult.SelectTab(this.tabPageMsg);
                    if (this.tabControlResult.Contains(tpResult)) this.tabControlResult.Controls.Remove(tpResult);
                    return;
                }

                if (dt.Columns.Count > 0)
                {
                    if (!this.tabControlResult.Contains(tpResult))
                    {
                        tpResult = new TabPage("结果");
                        tpResult.Name = "tpResult";
                        this.tabControlResult.Controls.Add(tpResult);
                    }
                    this.tabControlResult.SelectTab(tpResult);
                    if (!tpResult.Contains(dgvResult))
                    {
                        dgvResult = new DataGridView();
                        dgvResult.Dock = DockStyle.Fill;
                        dgvResult.AllowUserToAddRows = false;
                        dgvResult.ColumnHeadersHeight = 25;
                        dgvResult.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
                        dgvResult.RowHeadersWidth = 20;
                        dgvResult.BackgroundColor = SystemColors.Window;
                        tpResult.Controls.Add(dgvResult);
                    }
                    this.rtbMsg.Text = string.Format("操作完成，{0}行受影响", dt.Rows.Count);
                    dgvResult.DataSource = dt;
                }
                this.rtbMsg.Text = "操作完成";
            }
        }

        private void ShowLoginError(string s)
        {
            this.lblLoginMsg.Text = s;
            this.lblLoginMsg.Location = new Point((this.pLogin.Width - this.lblLoginMsg.Width) / 2, this.lblLoginMsg.Location.Y);
        }

        #endregion
    }
}
